<template>
  <div class="camera-container">
    <!-- 紧急警报弹框 -->
    <div v-if="showEmergencyAlert" class="emergency-alert-overlay" @click="closeEmergencyAlert">
      <div class="emergency-alert-modal" @click.stop>
        <div class="alert-header">
          <h2>🚨 紧急警报</h2>
          <button class="close-btn" @click="closeEmergencyAlert">×</button>
        </div>
        <div class="alert-content">
          <div class="alert-level">异常行为等级：<span class="level-3-badge">3级（紧急）</span></div>
          <div class="alert-prediction">{{ latestEmergencyAlert?.predict }}</div>
          <div class="alert-reason"><strong>检测原因：</strong>{{ latestEmergencyAlert?.reason }}</div>
          <div class="alert-time">检测时间：{{ latestEmergencyAlert ? formatTime(latestEmergencyAlert.timestamp) : '' }}</div>
        </div>
        <div class="alert-actions">
          <button class="acknowledge-btn" @click="acknowledgeAlert">已确认</button>
          <button class="mute-btn" @click="toggleAlertSound">{{ isAlertMuted ? '启用声音' : '静音警报' }}</button>
        </div>
      </div>
    </div>

    <div class="status-bar">
      <div class="connection-status" :class="{ connected: isConnected, reconnecting: isReconnecting }">
        <div class="status-indicator"></div>
        <span>{{ connectionStatusText }}</span>
      </div>
      
      <div class="camera-status" v-if="isConnected" :class="{ paused: isPaused }">
        <div class="status-indicator"></div>
        <span>{{ isPaused ? '摄像头已暂停' : '摄像头运行中' }}</span>
      </div>
      
      <!-- 紧急警报指示器 -->
      <div v-if="hasActiveEmergency" class="emergency-indicator" @click="showEmergencyAlert = true">
        <div class="emergency-pulse"></div>
        <span>🚨 紧急状况</span>
      </div>
      
      <div class="frame-info" v-if="lastFrameTime">
        最后更新: {{ formatTime(lastFrameTime) }}
      </div>
    </div>
    
    <div class="camera-preview">
      <div class="preview-box" :class="{ loading: isLoading }">
        <img v-if="imageData" :src="imageData" alt="摄像头实时图像" @load="handleImageLoaded" />
        <div v-else class="no-image">
          <div v-if="isReconnecting || isLoading" class="loading-spinner"></div>
          <span>{{ imageLoadingText }}</span>
        </div>
      </div>
        <div class="analysis-panel">
        <div class="analysis-header">
          <h3>康养照护异常行为预测</h3>
          <span class="frame-count" v-if="frameCount > 0">已接收 {{ frameCount }} 帧</span>
        </div>
        
        <div class="analysis-result">
          <div v-if="analysisResults.length > 0">
            <div 
              v-for="(result, index) in analysisResults" 
              :key="index" 
              class="result-item"
              :class="{ 
                active: index === 0,
                'level-1': result.level === 1,
                'level-2': result.level === 2,
                'level-3': result.level === 3
              }"
            >
              <div class="result-time">{{ formatTime(result.timestamp) }}</div>
              
              <!-- 结构化预测结果显示 -->
              <div v-if="result.level && result.reason && result.predict" class="prediction-content">
                <div class="prediction-header">
                  <span class="level-badge" :class="`level-${result.level}`">
                    等级 {{ result.level }}
                  </span>
                  <span class="predict-text">{{ result.predict }}</span>
                </div>
                <div class="reason-text">
                  <strong>原因：</strong>{{ result.reason }}
                </div>
              </div>
              
              <!-- 传统文本结果显示（fallback） -->
              <div v-else-if="result.text" class="result-content">
                {{ result.text }}
              </div>
            </div>
          </div>
          <div v-else class="no-result">
            <span>{{ analysisLoadingText }}</span>
          </div>
        </div>
      </div>
    </div>
      <div class="control-panel">
      <button @click="reconnect" :disabled="isConnected && !connectionError">
        {{ isConnected ? '重新连接' : isReconnecting ? '连接中...' : '连接' }}
      </button>
      
      <button @click="togglePause" :disabled="!isConnected || pauseLoading" class="pause-button">
        <span v-if="pauseLoading" class="loading-spinner-small"></span>
        {{ pauseLoading ? '处理中...' : (isPaused ? '恢复' : '暂停') }}
      </button>
      
      <button @click="clearResults" :disabled="analysisResults.length === 0">
        清除记录
      </button>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onBeforeUnmount } from 'vue';

interface AnalysisResult {
  text?: string;
  level?: number;
  reason?: string;
  predict?: string;
  timestamp: Date;
  confidence?: number;
}

// 状态变量
const socket = ref<WebSocket | null>(null);
const isConnected = ref(false);
const isReconnecting = ref(false);
const connectionError = ref(false);
const isLoading = ref(true);
const isPaused = ref(false);
const pauseLoading = ref(false);
const imageData = ref<string | null>(null);
const analysisResults = ref<AnalysisResult[]>([]);
const frameCount = ref(0);
const lastFrameTime = ref<Date | null>(null);
const reconnectAttempts = ref(0);
const reconnectTimer = ref<number | null>(null);
const maxReconnectAttempts = 5;
const reconnectDelay = 3000; // 3秒重连间隔

// 紧急警报相关状态
const showEmergencyAlert = ref(false);
const latestEmergencyAlert = ref<AnalysisResult | null>(null);
const hasActiveEmergency = ref(false);
const isAlertMuted = ref(false);
const alertAudioContext = ref<AudioContext | null>(null);
const emergencyAlertTimeout = ref<number | null>(null);

// 计算属性
const connectionStatusText = computed(() => {
  if (isConnected.value) return '已连接';
  if (isReconnecting.value) return `重新连接中 (${reconnectAttempts.value}/${maxReconnectAttempts})`;
  if (connectionError.value) return '连接失败';
  return '未连接';
});

const imageLoadingText = computed(() => {
  if (isReconnecting.value) return '正在连接服务器...';
  if (isLoading.value) return '正在等待图像...';
  return '无图像数据';
});

const analysisLoadingText = computed(() => {
  if (isReconnecting.value) return '正在连接服务器...';
  if (!isConnected.value) return '未连接到服务器';
  return '等待分析结果...';
});

// 处理图像加载完成
const handleImageLoaded = () => {
  isLoading.value = false;
};

// 格式化时间
const formatTime = (date: Date): string => {
  const hours = date.getHours().toString().padStart(2, '0');
  const minutes = date.getMinutes().toString().padStart(2, '0');
  const seconds = date.getSeconds().toString().padStart(2, '0');
  return `${hours}:${minutes}:${seconds}`;
};

// 连接 WebSocket
const connectWebSocket = () => {
  isReconnecting.value = reconnectAttempts.value > 0;
  isLoading.value = true;
  connectionError.value = false;
  
  // 这里使用相对路径，确保在部署时能正确连接到后端
  // 如果前后端部署在不同域，需要修改为完整的 URL
  const wsUrl = 'ws://localhost:8080/ws/video';
  
  try {
    socket.value = new WebSocket(wsUrl);
    
    socket.value.onopen = () => {
      isConnected.value = true;
      isReconnecting.value = false;
      reconnectAttempts.value = 0;
      console.log('WebSocket 连接成功');
    };
    
    socket.value.onclose = (event) => {
      isConnected.value = false;
      console.log('WebSocket 连接已关闭', event.code, event.reason);
      
      // 如果不是用户主动关闭的连接，尝试重连
      if (!event.wasClean) {
        scheduleReconnect();
      }
    };
    
    socket.value.onerror = (error) => {
      isConnected.value = false;
      connectionError.value = true;
      console.error('WebSocket 错误:', error);
      
      // WebSocket 错误通常会紧跟一个 onclose 事件，所以这里不需要主动关闭
    };      socket.value.onmessage = (event) => {
      try {
        const data = JSON.parse(event.data);
        frameCount.value++;
        lastFrameTime.value = new Date();
        
        // 添加调试日志
        console.log('收到WebSocket消息:', data);
        
        // 更新图像
        if (data.image) {
          imageData.value = data.image;
        }
        
        // 处理不同类型的消息
        if (data.type === 'analysis') {
          // 康养照护异常行为预测结果
          if (data.level && data.reason && data.predict) {
            // 结构化预测结果
            const newResult: AnalysisResult = {
              level: data.level,
              reason: data.reason,
              predict: data.predict,
              timestamp: new Date(data.timestamp || Date.now())
            };
            
            console.log('添加分析结果:', newResult);
            analysisResults.value.unshift(newResult);
            
            // 检查是否为紧急情况（level 3）
            if (data.level === 3) {
              console.log('检测到level 3，触发紧急警报!');
              triggerEmergencyAlert(newResult);
            }
          } else if (data.result) {
            // 传统文本结果（fallback）
            analysisResults.value.unshift({
              text: data.result,
              timestamp: new Date(data.timestamp || Date.now())
            });
          }
        } else if (data.type === 'error' && data.result) {
          // 错误信息
          analysisResults.value.unshift({
            text: `❌ ${data.result}`,
            timestamp: new Date(data.timestamp || Date.now())
          });
        }
        // 移除兼容旧格式的部分，只显示明确标记为analysis的消息
        
        // 最多保留10条记录
        if (analysisResults.value.length > 10) {
          analysisResults.value.pop();
        }
      } catch (error) {
        console.error('解析消息失败:', error);
      }
    };
  } catch (error) {
    console.error('创建 WebSocket 连接失败:', error);
    connectionError.value = true;
    scheduleReconnect();
  }
};

// 安排重连
const scheduleReconnect = () => {
  if (reconnectAttempts.value < maxReconnectAttempts) {
    reconnectAttempts.value++;
    isReconnecting.value = true;
    
    if (reconnectTimer.value) {
      window.clearTimeout(reconnectTimer.value);
    }
    
    console.log(`计划 ${reconnectDelay}ms 后重新连接 (尝试 ${reconnectAttempts.value}/${maxReconnectAttempts})`);
    reconnectTimer.value = window.setTimeout(() => {
      reconnect();
    }, reconnectDelay);
  } else {
    isReconnecting.value = false;
    console.log('达到最大重连次数，停止重连');
  }
};

// 重新连接
const reconnect = () => {
  if (socket.value) {
    socket.value.close();
  }
  
  if (reconnectTimer.value) {
    window.clearTimeout(reconnectTimer.value);
    reconnectTimer.value = null;
  }
  
  connectWebSocket();
};

// 清除结果
const clearResults = () => {
  analysisResults.value = [];
};

// 暂停/恢复摄像头
const togglePause = async () => {
  if (pauseLoading.value) return;
  
  pauseLoading.value = true;
  
  try {
    const endpoint = isPaused.value ? '/api/camera/resume' : '/api/camera/pause';
    const response = await fetch(`http://localhost:8080${endpoint}`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
    });
    
    if (response.ok) {
      const result = await response.json();
      if (result.success) {
        isPaused.value = !isPaused.value;
        console.log(`摄像头${isPaused.value ? '已暂停' : '已恢复'}`);
      } else {
        console.error('操作失败:', result.message);
        alert(`操作失败: ${result.message}`);
      }
    } else {
      console.error('请求失败:', response.status);
      alert('请求失败，请检查服务器连接');
    }
  } catch (error) {
    console.error('暂停/恢复操作失败:', error);
    alert('操作失败，请检查网络连接');
  } finally {
    pauseLoading.value = false;
  }
};

// 获取摄像头状态
const getCameraStatus = async () => {
  try {
    const response = await fetch('http://localhost:8080/api/camera/status');
    if (response.ok) {
      const result = await response.json();
      if (result.success) {
        isPaused.value = result.data.paused;
      }
    }
  } catch (error) {
    console.error('获取摄像头状态失败:', error);
  }
};

// 紧急警报相关函数
const triggerEmergencyAlert = (alertData: AnalysisResult) => {
  console.log('🚨 触发紧急警报:', alertData);
  latestEmergencyAlert.value = alertData;
  hasActiveEmergency.value = true;
  showEmergencyAlert.value = true;
  
  console.log('警报状态更新:', {
    latestEmergencyAlert: latestEmergencyAlert.value,
    hasActiveEmergency: hasActiveEmergency.value,
    showEmergencyAlert: showEmergencyAlert.value,
    isAlertMuted: isAlertMuted.value
  });
  
  // 播放警报声音
  if (!isAlertMuted.value) {
    console.log('播放警报声音');
    playAlertSound();
  } else {
    console.log('警报声音已静音');
  }
  
  // 自动关闭警报（30秒后）
  if (emergencyAlertTimeout.value) {
    clearTimeout(emergencyAlertTimeout.value);
  }
  emergencyAlertTimeout.value = window.setTimeout(() => {
    console.log('30秒后自动清除紧急状态');
    hasActiveEmergency.value = false;
  }, 30000);
};

const closeEmergencyAlert = () => {
  showEmergencyAlert.value = false;
};

const acknowledgeAlert = () => {
  showEmergencyAlert.value = false;
  hasActiveEmergency.value = false;
  if (emergencyAlertTimeout.value) {
    clearTimeout(emergencyAlertTimeout.value);
    emergencyAlertTimeout.value = null;
  }
};

const toggleAlertSound = () => {
  isAlertMuted.value = !isAlertMuted.value;
  if (isAlertMuted.value) {
    // 如果静音，保存到本地存储
    localStorage.setItem('emergencyAlertMuted', 'true');
  } else {
    localStorage.removeItem('emergencyAlertMuted');
  }
};

const playAlertSound = () => {
  try {
    // 初始化音频上下文
    if (!alertAudioContext.value) {
      alertAudioContext.value = new (window.AudioContext || (window as any).webkitAudioContext)();
    }
    
    const context = alertAudioContext.value;
    
    // 创建震撼的紧急警报声
    const createBeep = (frequency: number, duration: number, startTime: number) => {
      const oscillator = context.createOscillator();
      const gainNode = context.createGain();
      
      oscillator.connect(gainNode);
      gainNode.connect(context.destination);
      
      oscillator.frequency.value = frequency;
      oscillator.type = 'square';
      
      gainNode.gain.setValueAtTime(0, startTime);
      gainNode.gain.linearRampToValueAtTime(0.3, startTime + 0.01);
      gainNode.gain.exponentialRampToValueAtTime(0.01, startTime + duration);
      
      oscillator.start(startTime);
      oscillator.stop(startTime + duration);
    };
    
    const now = context.currentTime;
    
    // 创建警报音序列：高音-低音-高音-低音
    createBeep(800, 0.3, now);
    createBeep(400, 0.3, now + 0.3);
    createBeep(800, 0.3, now + 0.6);
    createBeep(400, 0.3, now + 0.9);
    
    // 1.5秒后重复
    setTimeout(() => {
      if (showEmergencyAlert.value && !isAlertMuted.value) {
        playAlertSound();
      }
    }, 1500);
    
  } catch (error) {
    console.error('播放警报声失败:', error);
  }
};

// 组件挂载时连接 WebSocket
onMounted(() => {
  connectWebSocket();
  // 获取初始暂停状态
  getCameraStatus();
  
  // 从本地存储恢复静音设置
  const mutedSetting = localStorage.getItem('emergencyAlertMuted');
  if (mutedSetting === 'true') {
    isAlertMuted.value = true;
  }
});

// 组件卸载前清理
onBeforeUnmount(() => {
  if (socket.value) {
    socket.value.close();
  }
  
  if (reconnectTimer.value) {
    window.clearTimeout(reconnectTimer.value);
  }
  
  if (emergencyAlertTimeout.value) {
    window.clearTimeout(emergencyAlertTimeout.value);
  }
  
  if (alertAudioContext.value) {
    alertAudioContext.value.close();
  }
});
</script>

<style scoped>
/* 紧急警报相关样式 */
.emergency-alert-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.8);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 9999;
  animation: fadeIn 0.3s ease-out;
}

.emergency-alert-modal {
  background: white;
  border-radius: 12px;
  padding: 0;
  max-width: 500px;
  width: 90%;
  box-shadow: 0 20px 60px rgba(220, 53, 69, 0.3);
  border: 3px solid #dc3545;
  animation: slideIn 0.3s ease-out;
}

.alert-header {
  background: linear-gradient(135deg, #dc3545, #c82333);
  color: white;
  padding: 20px;
  border-radius: 9px 9px 0 0;
  display: flex;
  justify-content: space-between;
  align-items: center;
  position: relative;
  overflow: hidden;
}

.alert-header::before {
  content: '';
  position: absolute;
  top: 0;
  left: -100%;
  width: 100%;
  height: 100%;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
  animation: sweep 2s infinite;
}

.alert-header h2 {
  margin: 0;
  font-size: 1.5rem;
  font-weight: bold;
  animation: pulse 1s infinite;
}

.close-btn {
  background: rgba(255, 255, 255, 0.2);
  border: none;
  color: white;
  font-size: 1.5rem;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background-color 0.2s;
}

.close-btn:hover {
  background: rgba(255, 255, 255, 0.3);
}

.alert-content {
  padding: 25px;
  text-align: center;
}

.alert-level {
  font-size: 1.1rem;
  margin-bottom: 15px;
  color: #333;
}

.level-3-badge {
  background: #dc3545;
  color: white;
  padding: 4px 12px;
  border-radius: 15px;
  font-weight: bold;
  font-size: 0.9rem;
}

.alert-prediction {
  font-size: 1.3rem;
  font-weight: bold;
  color: #dc3545;
  margin: 20px 0;
  padding: 15px;
  background: #fff5f5;
  border-radius: 8px;
  border: 1px solid #fecaca;
}

.alert-reason {
  font-size: 1rem;
  color: #666;
  margin: 15px 0;
  line-height: 1.5;
}

.alert-time {
  font-size: 0.9rem;
  color: #999;
  margin-top: 15px;
}

.alert-actions {
  padding: 20px 25px;
  display: flex;
  gap: 15px;
  border-top: 1px solid #eee;
}

.acknowledge-btn {
  flex: 1;
  background: #dc3545;
  color: white;
  border: none;
  padding: 12px 20px;
  border-radius: 6px;
  font-size: 1rem;
  font-weight: bold;
  cursor: pointer;
  transition: background-color 0.2s;
}

.acknowledge-btn:hover {
  background: #c82333;
}

.mute-btn {
  background: #6c757d;
  color: white;
  border: none;
  padding: 12px 20px;
  border-radius: 6px;
  font-size: 0.9rem;
  cursor: pointer;
  transition: background-color 0.2s;
  white-space: nowrap;
}

.mute-btn:hover {
  background: #5a6268;
}

.emergency-indicator {
  background: #dc3545;
  color: white;
  padding: 8px 15px;
  border-radius: 20px;
  font-weight: bold;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 8px;
  animation: urgentPulse 1s infinite;
  transition: transform 0.2s;
}

.emergency-indicator:hover {
  transform: scale(1.05);
}

.emergency-pulse {
  width: 12px;
  height: 12px;
  background: white;
  border-radius: 50%;
  animation: pulse 1s infinite;
}

@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes slideIn {
  from { 
    opacity: 0; 
    transform: translateY(-50px) scale(0.9); 
  }
  to { 
    opacity: 1; 
    transform: translateY(0) scale(1); 
  }
}

@keyframes sweep {
  0% { left: -100%; }
  100% { left: 100%; }
}

@keyframes pulse {
  0% { opacity: 1; }
  50% { opacity: 0.7; }
  100% { opacity: 1; }
}

@keyframes urgentPulse {
  0% { background: #dc3545; }
  50% { background: #ff4757; }
  100% { background: #dc3545; }
}

.camera-container {
  background-color: white;
  border-radius: 8px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
  padding: 20px;
  margin-bottom: 20px;
  transition: all 0.3s ease;
}

.status-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
}

.connection-status {
  padding: 8px 12px;
  border-radius: 4px;
  background-color: #f8d7da;
  color: #721c24;
  font-weight: bold;
  display: flex;
  align-items: center;
  gap: 8px;
  transition: all 0.3s ease;
}

.status-indicator {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background-color: #dc3545;
}

.connection-status.connected {
  background-color: #d4edda;
  color: #155724;
}

.connection-status.connected .status-indicator {
  background-color: #28a745;
}

.connection-status.reconnecting {
  background-color: #fff3cd;
  color: #856404;
}

.connection-status.reconnecting .status-indicator {
  background-color: #ffc107;
  animation: blink 1s infinite;
}

.camera-status {
  padding: 8px 12px;
  border-radius: 4px;
  background-color: #d4edda;
  color: #155724;
  font-weight: bold;
  display: flex;
  align-items: center;
  gap: 8px;
  transition: all 0.3s ease;
}

.camera-status .status-indicator {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background-color: #28a745;
}

.camera-status.paused {
  background-color: #fff3cd;
  color: #856404;
}

.camera-status.paused .status-indicator {
  background-color: #ffc107;
}

@keyframes blink {
  0% { opacity: 0.3; }
  50% { opacity: 1; }
  100% { opacity: 0.3; }
}

.frame-info {
  color: #6c757d;
  font-size: 0.9em;
}

.camera-preview {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  margin-bottom: 20px;
}

.preview-box {
  flex: 1;
  min-width: 320px;
  border: 1px solid #ddd;
  border-radius: 4px;
  overflow: hidden;
  background-color: #f8f9fa;
  height: 300px;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  transition: all 0.3s ease;
}

.preview-box.loading {
  background-color: #eef2f7;
}

.preview-box img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  transition: opacity 0.3s ease;
}

.no-image {
  color: #6c757d;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}

.loading-spinner {
  width: 30px;
  height: 30px;
  border: 3px solid rgba(0, 123, 255, 0.2);
  border-top-color: #007bff;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

.analysis-panel {
  flex: 1;
  min-width: 300px;
  display: flex;
  flex-direction: column;
  border: 1px solid #ddd;
  border-radius: 4px;
  background-color: #f8f9fa;
  overflow: hidden;
}

.analysis-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 15px;
  background-color: #e9ecef;
  border-bottom: 1px solid #ddd;
}

.analysis-header h3 {
  margin: 0;
  color: #2c3e50;
  font-size: 1rem;
}

.frame-count {
  font-size: 0.8rem;
  color: #6c757d;
}

.analysis-result {
  flex: 1;
  padding: 0;
  overflow-y: auto;
  max-height: 250px;
}

.result-item {
  padding: 10px 15px;
  border-bottom: 1px solid #eee;
  transition: background-color 0.2s;
}

.result-item.active {
  background-color: #e8f4ff;
}

.result-time {
  font-size: 0.8rem;
  color: #6c757d;
  margin-bottom: 5px;
}

.result-content {
  white-space: pre-wrap;
  color: #495057;
}

/* 异常行为预测相关样式 */
.prediction-content {
  color: #495057;
}

.prediction-header {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 8px;
}

.level-badge {
  padding: 2px 8px;
  border-radius: 12px;
  font-size: 0.75rem;
  font-weight: bold;
  color: white;
}

.level-badge.level-1 {
  background-color: #28a745;
}

.level-badge.level-2 {
  background-color: #ffc107;
  color: #212529;
}

.level-badge.level-3 {
  background-color: #dc3545;
}

.predict-text {
  font-weight: bold;
  font-size: 0.9rem;
}

.reason-text {
  font-size: 0.85rem;
  color: #6c757d;
  line-height: 1.4;
}

/* 结果项根据等级的背景色 */
.result-item.level-1 {
  border-left: 4px solid #28a745;
}

.result-item.level-2 {
  border-left: 4px solid #ffc107;
}

.result-item.level-3 {
  border-left: 4px solid #dc3545;
  background-color: #fff5f5;
}

.result-item.level-3.active {
  background-color: #ffe6e6;
}

.no-result {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100px;
  color: #6c757d;
}

.control-panel {
  display: flex;
  gap: 10px;
  margin-top: 20px;
}

button {
  background-color: #007bff;
  color: white;
  border: none;
  border-radius: 4px;
  padding: 8px 16px;
  cursor: pointer;
  font-size: 14px;
  transition: background-color 0.2s;
  display: flex;
  align-items: center;
  gap: 5px;
}

button:hover:not(:disabled) {
  background-color: #0069d9;
}

button:disabled {
  background-color: #6c757d;
  cursor: not-allowed;
  opacity: 0.7;
}

button:nth-child(2) {
  background-color: #6c757d;
}

button:nth-child(2):hover:not(:disabled) {
  background-color: #5a6268;
}

.pause-button {
  background-color: #ffc107 !important;
  color: #212529 !important;
}

.pause-button:hover:not(:disabled) {
  background-color: #e0a800 !important;
}

.pause-button:disabled {
  background-color: #6c757d !important;
  color: white !important;
}

.loading-spinner-small {
  width: 12px;
  height: 12px;
  border: 2px solid rgba(255, 255, 255, 0.3);
  border-top-color: #212529;
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin-right: 5px;
}

@media (max-width: 768px) {
  .status-bar {
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
  }
  
  .camera-preview {
    flex-direction: column;
  }
  
  .preview-box, .analysis-panel {
    width: 100%;
  }
  
  .preview-box {
    height: 240px;
  }
  
  .analysis-result {
    max-height: 200px;
  }
  
  .control-panel {
    flex-wrap: wrap;
  }
}
</style>
